package cn.weekdragon.gscore.adapter.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.weekdragon.gscore.adapter.bot.Bot;
import cn.weekdragon.gscore.adapter.bot.BotManager;
import cn.weekdragon.gscore.adapter.model.EventExt;
import cn.weekdragon.gscore.adapter.model.enums.EventEnum;
import cn.weekdragon.gscore.adapter.model.message.*;
import cn.weekdragon.gscore.adapter.service.WsReverseService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;
import lombok.extern.slf4j.Slf4j;
import org.java_websocket.handshake.ServerHandshake;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

@Slf4j
public class GsCoreService extends WsReverseService {

    private static final SimplePropertyPreFilter filter = new SimplePropertyPreFilter();
    static {
        filter.getExcludes().add("data");
    }
    public GsCoreService(String wsReverse, String serviceName, String authorization) throws URISyntaxException {
        super(wsReverse, serviceName, authorization);
    }

    @Override
    public void onOpen(ServerHandshake handshakedata) {
        super.onOpen(handshakedata);
        log.info("service({}) 连接成功...", serviceName);
    }

    @Override
    public void onMessage(String message) {
        receiveGsCoreMessage(message);
    }

    @Override
    public void onClose(int code, String reason, boolean remote) {
        super.onClose(code, reason, remote);
        log.info("service({}) 关闭：{}", serviceName,reason);
    }

    @Override
    public void onError(Exception ex) {
        super.onError(ex);
    }

    @Override
    public void receiveMessage(EventExt eventExt) {
        if(!this.wsClient.isOpen()){
            return;
        }
        processMessage(eventExt);

    }

    private void receiveGsCoreMessage(String message) {
        JSONObject coreMessage = JSON.parseObject(message);
        log.info("service({}) 收到消息：{}", serviceName,JSON.toJSONString(coreMessage,filter));
        String connectId = coreMessage.getString("bot_self_id");
        String messageId = coreMessage.getString("msg_id");
        if(StrUtil.isEmpty(connectId) || StrUtil.isEmpty(connectId)){
            return;
        }
        Optional<Bot> botById = BotManager.getBotById(connectId);
        botById.ifPresent(bot -> {
            String targetType = coreMessage.getString("target_type");
            EventExt ext = new EventExt();
            try {
                EventExt.setCurrent(ext);
                ext.setMsgSeq(messageId);
                if("group".equals(targetType)){
                    // 群消息
                    String groupId = coreMessage.getString("target_id");
                    ext.setGroupId(groupId);
                    Message chain = convertGsCoreMessage(coreMessage.getJSONArray("content"));
                    bot.sendGroupMessage(groupId,chain);
                }
            } finally {
                EventExt.clear();
            }
        });

//        List<Route> bots = RouteManager.getBots(this.getServiceName());
//        for (Route route : bots) {
//            Optional<Bot> botByName = BotManager.getBotByName(route.getBot());
//            if(botByName.isPresent()){
//                String targetType = coreMessage.getString("target_type");
//                EventExt ext = new EventExt();
//                try {
//                    EventExt.setCurrent(ext);
//                    ext.setMsgSeq(messageId);
//                    if("group".equals(targetType)){
//                        // 群消息
//                        String groupId = coreMessage.getString("target_id");
//                        ext.setGroupId(groupId);
//                        Message chain = convertGsCoreMessage(coreMessage.getJSONArray("content"));
//                        botByName.get().sendGroupMessage(groupId,chain);
//                    }
//                } finally {
//                    EventExt.clear();
//                }
//                break;
//            }
//        }
    }

        private Message convertGsCoreMessage(JSONArray content) {
        MessageChain chain = new MessageChain();
        for (int i = 0; i < content.size(); i++) {
            JSONObject item = content.getJSONObject(i);
            String type = item.getString("type");
            if("image".equals(type)){
                Image image = new Image();
                image.setBase64(item.getString("data").substring(9));
                chain.plus(image);
            }else if("text".equals(type)){
                chain.plus(item.getString("data"));
            }else if("node".equals(type)){
                Message data = convertGsCoreMessage(item.getJSONArray("data"));
                // 伪造消息目前还无法直接发图片，因此暂时先直接发出来
//                ForwardNode forwardNode = new ForwardNode(null,null,data);
//                chain.plus(forwardNode);
                chain.plus(data);
            }
        }
        return chain;
    }

    private void processMessage(EventExt eventExt) {
        JSONObject gsCoreMessage = convert2GsMessage(eventExt);
        if(Objects.nonNull(gsCoreMessage)){
            send(gsCoreMessage.toJSONString());;
        }
    }



    private JSONObject convert2GsMessage(EventExt ext) {
        JSONObject gsCoreMessage = new JSONObject();
        gsCoreMessage.put("bot_id","redProtocol");
        gsCoreMessage.put("bot_self_id",ext.getConnectId());
        gsCoreMessage.put("msg_id",ext.getMsgSeq());
        if(EventEnum.GROUP_MESSAGE.getType().equals(ext.getType())){
            gsCoreMessage.put("user_type","group");
        }else{
            gsCoreMessage.put("user_type","direct");
        }
        gsCoreMessage.put("group_id",ext.getGroupId());
        gsCoreMessage.put("user_id",ext.getUserId());
        gsCoreMessage.put("user_pm",3);

        MessageChain messageChain = ext.getInMessage();
        List<JSONObject> messages = new ArrayList<>();
        gsCoreMessage.put("content",messages);
        for (Message message : messageChain.toList()) {
            if(message instanceof Plain plain){
                JSONObject item = new JSONObject();
                item.put("type","text");
                String text = plain.getText();
//                if(StrUtil.isNotEmpty(Cons.commandPrefix) && text.startsWith(Cons.commandPrefix)){
//                    text = text.substring(Cons.commandPrefix.length());
//                }
                item.put("data",text);
                messages.add(item);
            }else if(message instanceof At at){
                JSONObject item = new JSONObject();
                item.put("type","at");
                item.put("data",at.getTarget());
                messages.add(item);
            }else if(message instanceof Quote quote){
                JSONObject item = new JSONObject();
                item.put("type","reply");
                item.put("data",quote.getMessageId());
                messages.add(item);
            }
        }

        if(CollectionUtil.isEmpty(messages)){
            return null;
        }
        return gsCoreMessage;
    }

    public void send(Object object) {
        send(JSON.toJSONString(object));
    }

    public void send(String text) {
        this.wsClient.send(StandardCharsets.UTF_8.encode(text));
    }

}
